/**
 * @file simulation.h
 * @brief 覆冰监测系统模拟模块接口
 * @version 1.1
 * @date 2023-05-22
 */

#ifndef SIMULATION_H
#define SIMULATION_H

#include <stdbool.h>
#include <stdint.h>
#include "common_defs.h"
#include "ice_calculation.h"
#include "uart_protocol.h" // 包含SensorDataPacket的定义
#include "visual_monitor.h" // 包含VisualIceData的定义
#include "stereo_monitor.h" // 包含StereoData的定义

#ifdef __cplusplus
extern "C" {
#endif

// 季节枚举定义
typedef enum {
    SEASON_SPRING = 0,     // 春季
    SEASON_SUMMER,         // 夏季
    SEASON_AUTUMN,         // 秋季
    SEASON_WINTER,         // 冬季
    SEASON_COUNT           // 季节数量
} SeasonType;

// 冬季覆冰阶段枚举定义
typedef enum {
    ICE_PHASE_NONE_START = 0,  // 无覆冰(初始)
    ICE_PHASE_GROWTH,          // 覆冰增长
    ICE_PHASE_STABLE,          // 覆冰保持
    ICE_PHASE_REDUCTION,       // 覆冰减少
    ICE_PHASE_NONE_END,        // 无覆冰(结束)
    ICE_PHASE_COUNT            // 阶段数量
} IcePhaseType;

// 模拟阶段枚举定义 (兼容旧代码)
typedef enum {
    SIMULATION_PHASE_NORMAL_WINTER = 0,   // 正常冬季
    SIMULATION_PHASE_SEVERE_WINTER,       // 严重冬季 
    SIMULATION_PHASE_EXTREME_WINTER,      // 极端冬季
    SIMULATION_PHASE_SPRING,              // 春季
    SIMULATION_PHASE_SUMMER,              // 夏季
    SIMULATION_PHASE_AUTUMN,              // 秋季
    SIMULATION_PHASE_MAX                  // 阶段数量
} SimulationPhase;

// 模拟数据结构
typedef struct {
    // 环境数据
    float temperature;     // 温度 (°C)
    float humidity;        // 湿度 (%)
    float wind_speed;      // 风速 (m/s)
    float wind_direction;  // 风向 (°)
    
    // 等值线缆数据
    float equivalent_ice_thickness;  // 等值线缆基准冰厚度 (mm)
    float equivalent_tension;        // 等值线缆拉力 (N)
    
    // 真实线缆数据
    float real_ice_thickness;        // 真实线缆基准冰厚度 (mm)
    
    // 模拟阶段 - 用于控制模拟数据随时间变化
    int simulation_phase;           // 模拟阶段（模式5下：0-4：无覆冰初始、覆冰增加、覆冰保持、覆冰减少、无覆冰结束；其他模式：0-3：正常、覆冰、冰融化、无冰）
    int phase_counter;              // 阶段内计数器
    float max_tension_increase;      // 模拟模式下的最大拉力增加量
    
    // 新增字段：季节和冰阶段
    SeasonType current_season;      // 当前季节
    IcePhaseType ice_phase;         // 冬季覆冰阶段
    uint64_t season_start_time;     // 当前季节开始时间(毫秒)
    uint64_t phase_start_time;      // 当前阶段开始时间(毫秒)
    float target_ice_thickness;     // 目标覆冰厚度(mm)
} SimulationData;

// 传感器模拟数据结构
typedef struct {
    float wind_speed;      // 风速(m/s)，精度0.01m/s
    float wind_direction;  // 风向(度)，精度1度
    float temperature;     // 温度(℃)，精度0.1℃
    float humidity;        // 湿度(%)，精度1%
    float tension1;        // 拉力1(kg)，精度0.03%
    float tension2;        // 拉力2(kg)，精度0.03%
    float battery_level;   // 电池电量(%)，精度1%
    float voltage;         // 电压(V)，精度0.1V
    int signal_strength;   // 信号强度(dBm)，精度1dBm
    bool use_random;       // 是否使用随机数据
} SensorMockData;

/**
 * @brief 初始化模拟模块
 * 
 * @return int 成功返回0，失败返回非0值
 */
int init_simulation(void);

/**
 * @brief 清理模拟模块
 */
void cleanup_simulation(void);

/**
 * @brief 更新模拟环境数据
 */
void update_simulation_environment(void);

/**
 * @brief 更新模拟覆冰厚度
 */
void update_simulation_ice_thickness(void);

/**
 * @brief 计算冰生长率
 * 
 * @param temperature 环境温度(°C)
 * @param humidity 相对湿度(%)
 * @param wind_speed 风速(m/s)
 * @return float 每次更新增加的覆冰厚度(mm)
 */
float calculate_ice_growth_rate(float temperature, float humidity, float wind_speed);

/**
 * @brief 获取模拟传感器数据
 * 
 * @param data 传感器数据包指针
 */
void get_simulation_sensor_data(SensorData *data);

/**
 * @brief 调整模拟数据
 * 
 * @param run_mode 运行模式
 * @param ice_density 冰密度
 */
void adjust_simulation_data(RunMode run_mode, float ice_density);

/**
 * @brief 根据传感器和视觉数据计算运行时冰厚度
 * 
 * @param sensor_thickness 传感器测量厚度
 * @param visual_thickness 视觉测量厚度
 * @param use_correction 是否使用修正
 * @return float 计算的冰厚度
 */
float calculate_runtime_ice_thickness(float sensor_thickness, float visual_thickness, bool use_correction);

/**
 * @brief 获取当前模拟数据
 * 
 * @return const SimulationData* 模拟数据指针（只读）
 */
const SimulationData* get_simulation_data(void);

/**
 * @brief 设置模拟数据
 * 
 * @param data 模拟数据指针
 */
void set_simulation_data(const SimulationData *data);

/**
 * @brief 重置模拟数据到默认状态
 */
void reset_simulation_data(void);

/**
 * @brief 模拟采集立体视觉数据
 * 
 * @param thickness 输出的冰厚度指针
 * @return int 成功返回1，失败返回0
 */
int simulate_stereo_data(float *thickness);

/**
 * @brief 模拟采集视觉数据
 * 
 * @param thickness 输出的冰厚度指针
 * @return int 成功返回1，失败返回0
 */
int simulate_visual_data(float *thickness);

/**
 * @brief 将模拟传感器数据转换为传感器数据包
 * 
 * @param data 输出的传感器数据包指针
 */
void convert_simulation_sensor_data(SensorDataPacket *data);

/**
 * @brief 填充模拟的立体视觉数据
 * 
 * @param data 输出的立体视觉数据指针
 * @param cable_diameter 线缆直径(mm)
 * @param current_time 当前时间戳
 * @return bool 成功返回true，失败返回false
 */
bool convert_simulation_stereo_data(StereoData *data, float cable_diameter, uint64_t current_time);

/**
 * @brief 填充模拟的视觉数据
 * 
 * @param data 输出的视觉数据指针
 * @param cable_diameter 线缆直径(mm)
 * @param current_time 当前时间戳
 * @return bool 成功返回true，失败返回false
 */
bool convert_simulation_visual_data(VisualIceData *data, float cable_diameter, uint64_t current_time);

/**
 * @brief 生成随机传感器数据
 * 从uart_handler.c移植过来的函数，用于生成随机的传感器数据
 */
void generate_random_sensor_data(void);

/**
 * @brief 获取传感器模拟数据
 * 
 * @return const SensorMockData* 传感器模拟数据指针（只读）
 */
const SensorMockData* get_sensor_mock_data(void);

/**
 * @brief 设置传感器模拟数据
 * 
 * @param data 传感器模拟数据指针
 */
void set_sensor_mock_data(const SensorMockData *data);

/**
 * @brief 设置传感器模拟模式
 * 
 * @param use_random 是否使用随机模拟数据
 */
void set_sensor_mock_mode(bool use_random);

/**
 * @brief 同步传感器随机数据与模拟环境数据
 */
void sync_sensor_mock_with_simulation(void);

/**
 * @brief 同步传感器数据与环境模拟数据
 * 
 * @param data 传感器数据指针
 */
void sync_sensor_data_with_simulation(SensorData *data);

/**
 * @brief 更新四季循环模拟状态
 * 
 * @param current_time 当前时间戳(毫秒)
 */
void update_season_cycle(uint64_t current_time);

/**
 * @brief 更新冬季覆冰阶段
 * 
 * @param current_time 当前时间戳(毫秒)
 */
void update_winter_ice_phase(uint64_t current_time);

/**
 * @brief 获取当前运行模式
 * 
 * @return RunMode 当前运行模式
 */
RunMode get_current_run_mode(void);

/**
 * @brief 获取当前采样模式
 * 
 * @return SampleMode 当前采样模式
 */
SampleMode get_current_sample_mode(void);

/**
 * @brief 获取当前季节的视觉特征参数
 * 
 * @param brightness 输出亮度系数(0.5-1.5)
 * @param contrast 输出对比度系数(0.8-1.2)
 * @param scene_color 输出场景色调(0=冷色调, 1=暖色调)
 * @param fog_density 输出雾气密度(0-1)
 * @param visible_range 输出可见距离系数(0.5-1.5)
 */
void get_season_visual_features(float *brightness, float *contrast, float *scene_color, 
                                float *fog_density, float *visible_range);

#ifdef __cplusplus
}
#endif

#endif /* SIMULATION_H */ 